package com.example.leetcode.trainingcamp.week3.Thursday;

/**
 * 三合一。描述如何只用一个数组来实现三个栈。
 *
 * <p>你应该实现push(stackNum,
 * value)、pop(stackNum)、isEmpty(stackNum)、peek(stackNum)方法。stackNum表示栈下标，value表示压入的值。
 *
 * <p>构造函数会传入一个stackSize参数，代表每个栈的大小。
 *
 * <p>来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/three-in-one-lcci
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class TripleInOne {

    private final int[] stack;
    private final boolean[] use;
    private final int size ;
    public TripleInOne(int stackSize) {
        stack = new int[stackSize *3];
        use = new boolean[stackSize *3];
        size = stackSize;
    }

    public void push(int stackNum, int value) {
        int indexEmpty = findIndexEmpty(stackNum);
        if (indexEmpty != -1){
            stack[indexEmpty] = value;
            use[indexEmpty] = true;
        }
    }

    public int pop(int stackNum) {
        if (size == 0){
            return -1;
        }
        int indexEmpty = findIndexEmpty(stackNum);
        if (indexEmpty == 0 || indexEmpty == size || indexEmpty == 2 * size){
            // 说明栈为空
            return -1;
        }
        if (indexEmpty == -1){
            // 栈满了
            use[(stackNum+1) * size - 1] = false;
            return stack[(stackNum+1) * size - 1];
        }
        // 栈未满且不为空
        use[indexEmpty -1] = false;
        return stack[indexEmpty-1];
    }

    public int peek(int stackNum) {
        if (size == 0){
            return -1;
        }
        int indexEmpty = findIndexEmpty(stackNum);
        if (indexEmpty == -1){
            // 说明没有找到空格
            return stack[(stackNum+1) * size -1];
        }
        if (indexEmpty == 0 || indexEmpty == size || indexEmpty == 2 * size){
            // 说明栈为空
            return -1;
        }
        return stack[indexEmpty-1];
    }

    public boolean isEmpty(int stackNum) {
        if (size == 0){
            return true;
        }
        int indexEmpty = findIndexEmpty(stackNum);
        return indexEmpty == 0 || indexEmpty == 2 * size || indexEmpty == size;
    }

    private int findIndexEmpty(int stackNum){
        for (int i = stackNum * size ; i<=(stackNum+1)*size -1;i++){
            if (!use[i]){
                return i;
            }
        }
        return -1;
    }
}


class TestTripleInOne{
  public static void main(String[] args) {
    TripleInOne one = new TripleInOne(18);
    System.out.println(one.peek(1));
    System.out.println(one.pop(2));
    System.out.println(one.isEmpty(1));
    one.push(2,40);
    System.out.println(one.pop(2));
    one.push(0,44);
    one.push(1,40);
    System.out.println(one.pop(0));
    one.push(1,54);
    one.push(0,42);
    System.out.println(one.isEmpty(0));
   // System.out.println(one.isEmpty(0));
  }
}